#include "Light.h"
#include "SceneNode.h"

namespace Nezha
{

	Light::Light(const _string& name)
		:mName(name)
		,mLitType(LT_POINT)
		,mEnabled(true)
		,mConstant(1.0f)
		,mLinear(0)
		,mQuadratic(0)
		,mRange(100.0f)
		,mIntensity(1.0f)
		,mAngle(NZ_PI)
		,mCosine(0)
		,mSine(0)
		,mExponent(0)
		,mPosition(Vector3::ZERO)
		,mDirection(Vector3::UNIT_Z)
		,mColor(RGBA::WHITE)
		,mCastShadow(false)
	{
	}

	Light::~Light()
	{

	}

	void Light::setAngle(float angle)
	{
		NZ_ASSERT(0 < angle && angle <= NZ_PI);

		mAngle = angle;
		mCosine = Cos(angle);
		mSine = Sin(angle);
	}

	void Light::setLightType(LightType lt)
	{
		mLitType = lt;
	}

	void Light::getBoundingSpere(Vector3& center, float& radius) const
	{
		center = mPosition;
		radius = mRange;
	}

	void Light::getBoundingBox(AABB& aabb) const
	{
		aabb.reset();
		aabb.mergeSphere(mPosition, mRange);
	}

	bool Light::isObjectAffected(SceneNode* sn) const
	{
		// TODO test culling mask?

		switch(mLitType)
		{
		case LT_DIRECTIONAL:
			{
				return true;
			}
			break;
		case LT_POINT:
			{
				const AABB& aabb = sn->getWorldAABB(0);
				Vector3 c;
				float r;
				getBoundingSpere(c, r);
				if(aabb.intersectSphere(c, r))
				{
					return true;
				}
			}
			break;
		case LT_SPOT:
			{

			}
			break;
		}

		return false;
	}

	void Light::updateShaderParam(ShaderParameter* sp) const
	{
		// TODO
	}

	LightList::LightList()
		:mNumLights(0)
	{
		memset(mLights, 0, sizeof(mLights));
	}

	void LightList::clear()
	{
		mNumLights = 0;
	}

	void LightList::addLight(Light* lit)
	{
		if(mNumLights < MAX_LENGTH)
		{
			mLights[mNumLights] = lit;
			++mNumLights;
		}
	}

	Light* LightList::getLight(u8 i)
	{
		if(i < mNumLights)
		{
			return mLights[i];
		}

		return NULL;
	}

	const int LightVectorReserve = 32;
	
	LightVector::LightVector()
		:mNumLights(0)
	{

	}

	void LightVector::clear()
	{
		mNumLights = 0;

		if(mLights.size() > LightVectorReserve)
		{
			mLights.resize(LightVectorReserve);
		}
	}

	void LightVector::addLight(Light* lit)
	{
		if(mLights.size() > mNumLights)
		{
			mLights[mNumLights] = lit;
		}
		else
		{
			mLights.push_back(lit);
		}

		++mNumLights;
	}

}//end namespace Nezha